home *** CD-ROM | disk | FTP | other *** search
/ Programming Microsoft Visual Basic .NET / Programming Microsoft Visual Basic .NET (Microsoft Press)(X08-78517)(2002).bin / 15 reflection / reflectiondemo / module1.vb < prev    next >
Encoding:
Text File  |  2002-03-20  |  27.8 KB  |  703 lines

  1. Imports System.Reflection
  2.  
  3. Module MainModule
  4.  
  5.     Sub Main()
  6.         ' Run one of the Textxxxx procedures below by uncommenting only one statement
  7.  
  8.         'TestAssembly()
  9.         'TestAssemblyEnumeration()
  10.         'TestAssemblyMethods()
  11.         'TestAssemblyName()
  12.         'TestModule()
  13.         'TestType()
  14.         'TestTypeEnumeration()
  15.         'TestMemberEnumeration()
  16.         'TestFindMembers()
  17.         'TestGetPropertyGetMethod()
  18.         'TestFilteredList()
  19.         'TestCallingSyntax()
  20.         'TestReadWriteFields()
  21.         'TestReadWriteProperties()
  22.         'TestReadWritePropertiesWithArgs()
  23.         'TestInvokeMethod()
  24.         'TestInvokeMember()
  25.         'TestObjectCreation()
  26.         'TestObjectCreation2()
  27.         'TestObjectCreation3()
  28.         'TestStackFrame()
  29.         'TestStackFrameFromException()
  30.  
  31.         ' You need these statements when running inside Visual Studio, so that
  32.         ' the Console window doesn't disappear
  33.         Console.WriteLine("")
  34.         Console.WriteLine(">>> Press Enter to terminate the program <<<")
  35.         Console.ReadLine()
  36.     End Sub
  37.  
  38.     ' this procedure tests basic Assembly properties
  39.  
  40.     Sub TestAssembly()
  41.         Dim asm As Reflection.Assembly                ' Assumes Imports System.Reflection.
  42.  
  43.         ' Get a reference to the assembly this code is running into.
  44.         asm = [Assembly].GetExecutingAssembly()
  45.         Console.WriteLine("GetExecutingAssembly method: " & asm.FullName)
  46.         Console.WriteLine("")
  47.  
  48.         ' Get a reference to an assembly given its file name.
  49.         ' (Replace with an actual file name to avoid the error.)
  50.         Try
  51.             asm = Reflection.Assembly.LoadFrom("c:\myapp\mylib.dll")
  52.             Console.WriteLine("LoadFrom method:" & asm.FullName)
  53.         Catch ex As Exception
  54.             Console.WriteLine("Unabble to find the assembly.")
  55.         End Try
  56.         Console.WriteLine("")
  57.  
  58.         ' Get a reference to the assembly that contains a given Type.
  59.         ' (The argument must be a System.Type value, so we need GetType.)
  60.         asm = Reflection.Assembly.GetAssembly(GetType(String))
  61.         Console.WriteLine("GetAssembly(GetType(String)) method: " & asm.FullName)
  62.         Console.WriteLine("")
  63.  
  64.         ' Get a reference to an assembly given its display name.
  65.         asm = Reflection.Assembly.Load("mscorlib")
  66.         Console.WriteLine("Load(""mscorlib"") method: " & asm.FullName)
  67.         Console.WriteLine("")
  68.  
  69.         Console.WriteLine("Location = " & asm.Location)
  70.         ' => C:/WINNT/Microsoft.NET/Framework/v1.0.3300/mscorlib.dll
  71.         Console.WriteLine("CodeBase = " & asm.CodeBase)
  72.         ' => file://C:/WINNT/Microsoft.NET/Framework/v1.0.3300/mscorlib.dll
  73.         ' (The actual location can of course be different on your system.)
  74.         Try
  75.             Console.WriteLine("EntryPoint = " & asm.EntryPoint.Name)
  76.         Catch ex As Exception
  77.             Console.WriteLine(ex.message)
  78.         End Try
  79.     End Sub
  80.  
  81.     ' this procedure tests enumeration of modules and types
  82.  
  83.     Sub TestAssemblyEnumeration()
  84.         Dim asm As [Assembly] = Reflection.Assembly.Load("mscorlib")
  85.  
  86.         ' Enumerate all the modules in an assembly.
  87.         Console.WriteLine("Modules in the assembly")
  88.         Dim mo As [Module]
  89.         For Each mo In asm.GetModules
  90.             Console.WriteLine(mo.FullyQualifiedName)
  91.         Next
  92.         Console.WriteLine("Press Enter to see all the types in the assembly")
  93.         Console.ReadLine()
  94.  
  95.         ' Enumerate all the types defined in an assembly.
  96.         Dim ty As Type
  97.         For Each ty In asm.GetTypes
  98.             Console.WriteLine(ty.FullName)
  99.         Next
  100.         Console.WriteLine("Press Enter to see all the exported types")
  101.         Console.ReadLine()
  102.  
  103.         For Each ty In asm.GetExportedTypes
  104.             Console.WriteLine(ty.FullName)
  105.         Next
  106.         Console.WriteLine("")
  107.     End Sub
  108.  
  109.     ' this procedure test basic methods of the Assembly class
  110.  
  111.     Sub TestAssemblyMethods()
  112.         Dim asm As [Assembly] = Reflection.Assembly.Load("mscorlib")
  113.  
  114.         ' Next statement assumes asm is pointing to MSCORLIB.
  115.         Dim ty As Type = asm.GetType("System.Int32")
  116.         Console.WriteLine(ty.FullName)
  117.         Console.WriteLine("")
  118.  
  119.         ' this returns Nothing, because the type isn't defined
  120.         ' (comparison is case-sensitive)
  121.         ty = asm.GetType("system.int32")
  122.         If ty Is Nothing Then
  123.             Console.WriteLine("The GetType method returned Nothing")
  124.         Else
  125.             Console.WriteLine(ty.FullName)
  126.         End If
  127.         Console.WriteLine("")
  128.  
  129.         ' this raises an exception because the name is compared in case-insensitive way
  130.         Try
  131.             ty = asm.GetType("system.int32", True)
  132.         Catch ex As Exception
  133.             Console.WriteLine(ex.Message)
  134.         End Try
  135.         Console.WriteLine("")
  136.  
  137.         ' This doesn't raise any exception because type name
  138.         ' is compared in case-insensitive way.
  139.         ty = asm.GetType("system.int32", True, True)
  140.         Console.WriteLine(ty.FullName)                  ' => System.Int32
  141.         Console.WriteLine("")
  142.  
  143.         ' A long-winded way to create an Integer.
  144.         Dim o As Object = asm.CreateInstance("System.Int32")
  145.         ' Prove that we have created an Integer.
  146.         Console.Write(o.GetType.FullName)               ' => System.Int32
  147.     End Sub
  148.  
  149.     ' this procedure tests the AssemblyName object
  150.  
  151.     Sub TestAssemblyName()
  152.         ' Get a reference to an assembly and its AssemblyName.
  153.         Dim asm As [Assembly] = Reflection.Assembly.Load("mscorlib")
  154.         Dim an As AssemblyName = asm.GetName
  155.  
  156.         ' (Of course you can get different output on your system, depending
  157.         '  on the runtime versions you've installed and system paths.)
  158.         Console.WriteLine(an.CodeBase)
  159.         ' => file://C:/WINNT/Microsoft.NET/Framework/v1.0.3300/mscorlib.dll
  160.         Console.WriteLine(an.FullName)
  161.         ' => mscorlib, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  162.  
  163.         ' These properties come from the Version dependent object.
  164.         Console.WriteLine(an.Version.Major)         ' => 1
  165.         Console.WriteLine(an.Version.Minor)         ' => 0
  166.         Console.WriteLine(an.Version.Build)         ' => 2204
  167.         Console.WriteLine(an.Version.Revision)      ' => 21
  168.         ' You can also get the version as a single number.
  169.         Console.WriteLine(an.Version.ToString)      ' => 1.0.21.2204
  170.         Console.WriteLine("")
  171.  
  172.         ' Display the hash code of the assembly as a comma-delimited
  173.         ' list of bytes.
  174.         Console.Write("PublicKey of mscorlib: ")
  175.         Dim b As Byte
  176.         For Each b In an.GetPublicKeyToken()
  177.             Console.Write(b.ToString & ",")
  178.         Next
  179.         Console.WriteLine("")
  180.  
  181.         ' Get information on all the assemblies the current assembly references.
  182.         Dim anArr() As AssemblyName
  183.         anArr = [Assembly].GetExecutingAssembly.GetReferencedAssemblies()
  184.         Console.WriteLine("Assemblies referenced by the running assembly:")
  185.         For Each an In anArr
  186.             Console.WriteLine(an.FullName)
  187.         Next
  188.         Console.WriteLine("")
  189.  
  190.         ' check whether the assembly can run side-by-side
  191.         Dim avc As System.Configuration.Assemblies.AssemblyVersionCompatibility
  192.         avc = an.VersionCompatibility
  193.         If (avc And Configuration.Assemblies.AssemblyVersionCompatibility. _
  194.             SameMachine) <> 0 Then
  195.             Console.WriteLine("The assembly can run side-by-side with other versions of " _
  196.                 & "this assembly running on the same machine")
  197.         End If
  198.     End Sub
  199.  
  200.     ' this procedure tests the Module object
  201.  
  202.     Sub TestModule()
  203.         Dim asm As [Assembly] = Reflection.Assembly.Load("mscorlib")
  204.         Dim mo As [Module]
  205.  
  206.         For Each mo In asm.GetModules
  207.             Console.WriteLine(mo.Name & " รป " & mo.ScopeName)
  208.             ' => mscorlib.dll - CommonLanguageRuntimeLibrary
  209.         Next
  210.  
  211.         ' get a reference to the only module in mscorlib.dll.
  212.         mo = asm.GetModule("CommonLanguageRuntimeLibrary")
  213.         Console.WriteLine(mo.FullyQualifiedName)
  214.         ' => c:\winnt\microsoft.net\framework\v1.0.2914\mscorlib.dll
  215.     End Sub
  216.  
  217.     ' this procedure tests the System.Type object
  218.  
  219.     Sub TestType()
  220.         ' get a Type object using VB's GetType function
  221.         Dim ty As Type = GetType(String)
  222.         Console.WriteLine(ty.FullName)      ' => System.String
  223.  
  224.         ' get a Type using the GetType method(inherited from System.Object)
  225.         Dim d As Double
  226.         ty = d.GetType
  227.         Console.WriteLine(ty.FullName)      ' => System.Double
  228.  
  229.         ' get a Type using the Type.GetType shared method
  230.         ty = Type.GetType("System.Int64")
  231.         Console.WriteLine(ty.FullName)      ' => System.Int64
  232.         Console.WriteLine()
  233.         ' 
  234.         ' Get the type buried in an assembly.
  235.         ty = Type.GetType("System.Data.DataSet, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
  236.         ' NOTE: the above statement fails under a different version of the runtime.
  237.         ' Here's how you can make it succeed always
  238.         Dim asm As [Assembly] = [Assembly].LoadWithPartialName("System.Data")
  239.         ty = Type.GetType("System.Data.DataSet, " & asm.FullName)
  240.  
  241.         ' Test the AssemblyQualifiedName
  242.         Console.WriteLine(GetType(String).AssemblyQualifiedName)
  243.         Console.WriteLine("")
  244.  
  245.         ' get the types for an array of objects.
  246.         Dim anArray() As Object = {"a string", 123%, #1/2/2001#}
  247.         Dim types() As Type = Type.GetTypeArray(anArray)
  248.         Console.WriteLine(types(0).FullName)        ' => System.String
  249.         Console.WriteLine(types(1).FullName)        ' => System.Int32
  250.         Console.WriteLine(types(2).FullName)        ' => System.DateTime
  251.         Console.WriteLine()
  252.  
  253.         ' Get the .NET object that wraps the Word.Application component.
  254.         Dim wordtype As Type = Type.GetTypeFromProgID("Word.Application")
  255.         ' Display information on the wrapping object.
  256.         Console.WriteLine(wordtype.Name)       ' => __ComObject
  257.         ' This is the CLSID value stored in the registry.
  258.         Console.WriteLine(wordtype.GUID)       ' => 000209ff-0000-0000-c000-000000000046
  259.         ' Get a reference through the CLSID.
  260.         Dim type2 As Type = Type.GetTypeFromCLSID(wordtype.GUID)
  261.         ' Prove that this is the same object.
  262.         Console.WriteLine(wordtype Is type2)   ' => True
  263.     End Sub
  264.  
  265.     ' this procedure enumerates all the types in mscorlib.dll
  266.  
  267.     Sub TestTypeEnumeration()
  268.         Dim asm As [Assembly] = Reflection.Assembly.Load("mscorlib")
  269.         Dim t As Type
  270.  
  271.         For Each t In asm.GetExportedTypes()
  272.             If t.IsClass Then
  273.                 Console.WriteLine(t.Name & " (Class)")
  274.             ElseIf t.IsEnum Then
  275.                 ' Note that an enum is also a value type, so we must 
  276.                 ' test for IsEnum before IsValueType.
  277.                 Console.WriteLine(t.Name & " (Enum)")
  278.             ElseIf t.IsValueType Then
  279.                 Console.WriteLine(t.Name & " (ValueType)")
  280.             ElseIf t.IsInterface Then
  281.                 Console.WriteLine(t.Name & " (Interface)")
  282.             Else
  283.                 ' This statements is never reached, because a type
  284.                 ' can't be something other than one of the above.
  285.             End If
  286.         Next
  287.     End Sub
  288.  
  289.     ' this procedure tests member enumeration
  290.  
  291.     Sub TestMemberEnumeration()
  292.         ' Get a reference to the System.String type.
  293.         Dim stringType As Type = Type.GetType("System.String")
  294.         Dim minfos() As MemberInfo
  295.         Dim mi As MemberInfo
  296.  
  297.         ' List all its members.
  298.         Console.WriteLine("All members of the System.String class:")
  299.         minfos = stringType.GetMembers()
  300.         For Each mi In minfos
  301.             Console.WriteLine(mi.Name)
  302.         Next
  303.         Console.WriteLine()
  304.  
  305.         ' Get all public, non-shared, non-inherited members of System.String.
  306.         Console.WriteLine("Press Enter to see all public, non-shared, non-inherited members of the System.String class:")
  307.         Console.ReadLine()
  308.         minfos = stringType.GetMembers(BindingFlags.Public _
  309.             Or BindingFlags.Instance Or BindingFlags.DeclaredOnly)
  310.         For Each mi In minfos
  311.             Console.WriteLine(mi.Name)
  312.         Next
  313.         Console.WriteLine()
  314.  
  315.         ' Get all the methods of System.String.
  316.         Console.WriteLine("Press Enter to see all the methods of the System.String class:")
  317.         Console.ReadLine()
  318.         For Each mi In GetType(String).GetMethods()
  319.             Console.WriteLine(mi.Name)
  320.         Next
  321.         Console.WriteLine()
  322.  
  323.         ' Get all the interfaces of System.String.
  324.         Console.WriteLine("Press Enter to see all the interfaces of the System.String class:")
  325.         Console.ReadLine()
  326.         Dim ty As Type
  327.         For Each ty In stringType.GetInterfaces()
  328.             Console.WriteLine(ty.Name)
  329.         Next
  330.     End Sub
  331.  
  332.     ' this procedure tests the FindMembers method
  333.  
  334.     Sub TestFindMembers()
  335.         ' Get a reference to the System.String type.
  336.         Dim stringType As Type = Type.GetType("System.String")
  337.         Dim minfos() As MemberInfo
  338.         Dim mi As MemberInfo
  339.  
  340.         ' Get only public, instance methods and properties
  341.         ' whose name begins with "C".
  342.         minfos = stringType.FindMembers( _
  343.             MemberTypes.Method Or MemberTypes.Property, _
  344.             BindingFlags.Public Or BindingFlags.Instance, _
  345.             AddressOf FilterByName, "C")
  346.  
  347.         ' List the results.
  348.         Console.WriteLine("Methods and Properties of System.String whose name starts with 'C'")
  349.         For Each mi In minfos
  350.             Console.WriteLine(mi.Name)
  351.         Next
  352.         Console.WriteLine()
  353.  
  354.         ' We're looking for properties and functions that return a 32-bit integer.
  355.         Dim returnType As Type = Type.GetType("System.Int32")
  356.         ' We're searching only public, non-shared methods and properties.
  357.         minfos = stringType.FindMembers( _
  358.             MemberTypes.Method Or MemberTypes.Property, _
  359.             BindingFlags.Public Or BindingFlags.Instance, _
  360.             AddressOf FilterByType, returnType)
  361.  
  362.         Console.WriteLine("Press Enter to see properties and methods that return an Integer value:")
  363.         Console.ReadLine()
  364.         For Each mi In minfos
  365.             Console.WriteLine(mi.Name)
  366.         Next
  367.         Console.WriteLine()
  368.     End Sub
  369.  
  370.     ' This filtering function returns True if the member name 
  371.     ' begins with the character passed as its second argument.
  372.     Function FilterByName(ByVal m As MemberInfo, _
  373.         ByVal filterCriteria As Object) As Boolean
  374.         If m.Name.StartsWith(filterCriteria.ToString) Then
  375.             Return True
  376.         End If
  377.     End Function
  378.  
  379.     ' Accept only properties and methods whose return value matches
  380.     ' the Type passed as the second argument.
  381.     Function FilterByType(ByVal m As MemberInfo, _
  382.         ByVal filterCriteria As Object) As Boolean
  383.  
  384.         If m.MemberType = MemberTypes.Property Then
  385.             ' If it is a property, cast MemberInfo to PropertyInfo.
  386.             Dim pi As PropertyInfo = CType(m, PropertyInfo)
  387.             ' Return True if the property type is the one we're looking for.
  388.             Return (pi.PropertyType Is filterCriteria)
  389.         ElseIf m.MemberType = MemberTypes.Method Then
  390.             ' If it is a method, cast MemberInfo to MethodInfo.
  391.             Dim mi As MethodInfo = CType(m, MethodInfo)
  392.             ' Return True if the return type is the one we're looking for.
  393.             Return (mi.ReturnType Is filterCriteria)
  394.         End If
  395.     End Function
  396.  
  397.     ' this procedure tests the GetProperty and GetMethod methods
  398.  
  399.     Sub TestGetPropertyGetMethod()
  400.         ' Test whether the Chars property is read-only.
  401.         Dim pi As PropertyInfo = GetType(String).GetProperty("Chars")
  402.         If pi.CanWrite Then
  403.             Console.WriteLine("The Chars property is writeable")
  404.         Else
  405.             Console.WriteLine("The Chars property is read-only")
  406.         End If
  407.         Console.WriteLine()
  408.  
  409.         ' Get the MethodInfo object for the IndexOf string method with the
  410.         ' following signature: IndexOf(char, startIndex, endIndex).
  411.  
  412.         ' Prepare the signature as an array of Type objects.
  413.         ' Note that you can define the type of arguments using either
  414.         ' the GetType function or the Type.GetType method.
  415.         Dim argTypes() As Type = {GetType(Char), _
  416.             Type.GetType("System.Int32"), Type.GetType("System.Int32")}
  417.         ' Ask for the method with given name and signature.
  418.         Dim mi As MethodInfo = GetType(String).GetMethod("IndexOf", argTypes)
  419.         Console.WriteLine("The IndexOf(Char, Integer, Integer) returns the following type: " & mi.ReturnType.FullName)
  420.     End Sub
  421.  
  422.     ' this procedure shows how to filter member lists
  423.  
  424.     Sub TestFilteredList()
  425.         ' Get a reference to the System.String type.
  426.         Dim stringType As Type = Type.GetType("System.String")
  427.         ' We use this ArrayList to keep track of items already displayed.
  428.         Dim al As New ArrayList()
  429.  
  430.         Dim mi As MemberInfo
  431.         For Each mi In stringType.GetMembers()
  432.             If (mi.MemberType And MemberTypes.Constructor) <> 0 Then
  433.                 ' Ignore constructor methods.
  434.             ElseIf Not al.Contains(mi.Name) Then
  435.                 ' If this element hasn't been listed yet, do it now.
  436.                 ' (The MemberType property returns an enumerated value, thus we can
  437.                 ' transform it into its textual description with the ToString method.)
  438.                 Console.WriteLine("{0}  ({1})", mi.Name, mi.MemberType.ToString)
  439.                 ' Add this element to the list of processed items.
  440.                 al.Add(mi.Name)
  441.             End If
  442.         Next
  443.     End Sub
  444.  
  445.     ' this procedure tests how to display the parameter signature of a method
  446.  
  447.     Sub TestCallingSyntax()
  448.         ' Get a reference to the System.String type.
  449.         Dim stringType As Type = Type.GetType("System.String")
  450.         ' Get the MethodInfo for the CopyTo method.
  451.         Dim mi As MethodInfo = stringType.GetMethod("CopyTo")
  452.         ' Get the ParameterInfo array for this method.
  453.         Dim pinfos() As ParameterInfo = mi.GetParameters
  454.         Dim i As Integer
  455.  
  456.         ' Display the calling syntax for this method.
  457.         Console.Write(mi.Name & "(")
  458.         For i = 0 To pinfos.GetUpperBound(0)
  459.             ' Display the parameter name.
  460.             Console.Write(pinfos(i).Name)
  461.             ' If not the last parameter, append a comma.
  462.             If i < pinfos.GetUpperBound(0) Then Console.Write(",")
  463.         Next
  464.         ' Display the closing parenthesis.
  465.         Console.WriteLine(")")
  466.     End Sub
  467.  
  468.     ' this procedure reads and writes fields
  469.  
  470.     Sub TestReadWriteFields()
  471.         ' Create a Person object.
  472.         Dim p As New Person("Joe", "Doe")
  473.         ' Reflect on it.
  474.         Dim ty As Type = p.GetType
  475.         ' Get a reference to its FirstName Field.
  476.         Dim fi As FieldInfo = ty.GetField("FirstName")
  477.         ' Display its current value.
  478.         Console.WriteLine(fi.GetValue(p))    ' => Joe
  479.         ' Change it.
  480.         fi.SetValue(p, "Robert")
  481.         ' Prove that it changed.
  482.         Console.WriteLine(p.FirstName)       ' => Robert
  483.     End Sub
  484.  
  485.     ' this procedure tests reading and writing parameterless properties
  486.  
  487.     Sub TestReadWriteProperties()
  488.         ' Get a Person object and reflect on it.
  489.         Dim p As New Person("Joe", "Doe")
  490.         Dim ty As Type = p.GetType
  491.         ' Set the Age property.
  492.         Dim pi As PropertyInfo = ty.GetProperty("Age")
  493.         ' Note that the type of value must match exactly.
  494.         ' (Integer constants must be converted to Short, in this case.)
  495.         pi.SetValue(p, 35S, Nothing)
  496.         ' Read it back.
  497.         Console.WriteLine(pi.GetValue(p, Nothing))   ' => 35
  498.     End Sub
  499.  
  500.     ' this procedure tests reading and writing properties with arguments
  501.  
  502.     Sub TestReadWritePropertiesWithArgs()
  503.         ' Get a Person object and reflect on it.
  504.         Dim p As New Person("Joe", "Doe")
  505.         Dim ty As Type = p.GetType
  506.         ' Get a reference to the PropertyInfo object
  507.         Dim pi As PropertyInfo = ty.GetProperty("EmailAddress")
  508.         ' Prepare the array of parameters.
  509.         Dim params() As Object = {1S}
  510.         ' Set the property.
  511.         pi.SetValue(p, "321 North Street", params)
  512.         ' Read it back.
  513.         Console.WriteLine(pi.GetValue(p, params))   ' => 321 North Street
  514.     End Sub
  515.  
  516.     ' this procedure tests invoking a method
  517.  
  518.     Sub TestInvokeMethod()
  519.         ' Get a Person object and reflect on it.
  520.         Dim p As New Person("Joe", "Doe")
  521.         Dim ty As Type = p.GetType
  522.         ' Get the MethodInfo for this method.
  523.         Dim mi As MethodInfo = ty.GetMethod("SendEmail")
  524.         ' Prepare an array for arguments with same number of expected parameters.
  525.         Dim params(mi.GetParameters.Length - 1) As Object
  526.         ' Set parameters values.
  527.         params(0) = "This is a message"
  528.         params(1) = 3
  529.         ' Invoke the method.
  530.         mi.Invoke(p, params)
  531.         Console.WriteLine()
  532.  
  533.         ' try again, but omit the Optional argument
  534.         params(0) = "This is another message"
  535.         params(1) = Type.Missing
  536.         mi.Invoke(p, params)
  537.         Console.WriteLine()
  538.  
  539.         ' try once again, but use a different technique
  540.         ' Retrieve the DefaultValue from the ParameterInfo object.
  541.         params(0) = "This is yet another message"
  542.         params(1) = mi.GetParameters(1).DefaultValue
  543.         mi.Invoke(p, params)
  544.     End Sub
  545.  
  546.     ' test the InvokeMember method
  547.  
  548.     Sub TestInvokeMember()
  549.         ' Create a Person object and get its corresponding Type object.
  550.         Dim p As New Person()
  551.         Dim ty As Type = p.GetType
  552.  
  553.         ' Set the FirstName field.
  554.         Dim args() As Object = {"Francesco"}    ' One argument.
  555.         ty.InvokeMember("FirstName", BindingFlags.SetField, Nothing, p, args)
  556.         Console.WriteLine("Set FirstName property through InvokeMember")
  557.  
  558.         ' Read the FirstName field.
  559.         ' (Note that we're passing Nothing for the argument array.)
  560.         Dim value As Object = ty.InvokeMember("FirstName", BindingFlags.GetField, _
  561.             Nothing, p, Nothing)
  562.         Console.WriteLine("FirstName is now {0}", value)
  563.  
  564.         ' Set the Age property.
  565.         Dim args2() As Object = {35S}    ' One argument.
  566.         ty.InvokeMember("Age", BindingFlags.SetProperty, Nothing, p, args2)
  567.         Console.WriteLine("Age is now {0}", p.Age)
  568.  
  569.         ' Call the SendEMail method.
  570.         Dim args3() As Object = {"This is a message", 2}
  571.         ty.InvokeMember("SendEmail", BindingFlags.InvokeMethod, Nothing, p, args3)
  572.     End Sub
  573.  
  574.     ' this procedure tests object creation using default constructor
  575.  
  576.     Sub TestObjectCreation()
  577.         ' Next statement assumes that the Person class is defined in
  578.         ' an assembly named "ReflectionDemo".
  579.         Dim ty As Type = Type.GetType("ReflectionDemo.Person")
  580.         Dim o As Object = Activator.CreateInstance(ty)
  581.         ' prove that we created a Person
  582.         Console.WriteLine("A {0} object has been created", o.GetType.Name)
  583.     End Sub
  584.  
  585.     ' this procedure tests object creator using a constructor that takes arguments
  586.  
  587.     Sub TestObjectCreation2()
  588.         Dim ty As Type = Type.GetType("ReflectionDemo.Person")
  589.         ' Use the constructor that takes two arguments.
  590.         Dim params() As Object = {"Joe", "Doe"}
  591.         ' Call the constructor that matches the parameter signature.
  592.         Dim o As Object = System.Activator.CreateInstance(ty, params)
  593.         ' prove that we created a Person and that arguments were passed correctly
  594.         Console.WriteLine("A {0} object has been created", o.GetType.Name)
  595.         Dim p As Person = CType(o, Person)
  596.         Console.WriteLine("FirstName = {0}, LastName = {1}", p.FirstName, p.LastName)
  597.     End Sub
  598.  
  599.     ' this procedure tests object creation by explicitly calling the constructor
  600.  
  601.     Sub TestObjectCreation3()
  602.         Dim ty As Type = Type.GetType("ReflectionDemo.Person")
  603.         ' Prepare the argument signature as an array of types (2 strings).
  604.         Dim types() As Type = {GetType(System.String), GetType(System.String)}
  605.         ' Get a reference to the correct constructor.
  606.         Dim ci As ConstructorInfo = ty.GetConstructor(types)
  607.         ' Prepare the parameters.
  608.         Dim params() As Object = {"Joe", "Doe"}
  609.         ' Invoke the constructor and assign the result to a variable. 
  610.         Dim o As Object = ci.Invoke(params)
  611.         ' prove that we created a Person and that arguments were passed correctly
  612.         Console.WriteLine("A {0} object has been created", o.GetType.Name)
  613.         Dim p As Person = CType(o, Person)
  614.         Console.WriteLine("FirstName = {0}, LastName = {1}", p.FirstName, p.LastName)
  615.     End Sub
  616.  
  617.     ' this procedure tests the StackFrame object
  618.  
  619.     Sub TestStackFrame()
  620.         ' call an inner procedure
  621.         TestStackFrame_1()
  622.     End Sub
  623.  
  624.     Sub TestStackFrame_1()
  625.         TestStackFrame_2()
  626.     End Sub
  627.  
  628.     Sub TestStackFrame_2()
  629.         Dim i As Integer
  630.         Dim st As New System.Diagnostics.StackTrace()
  631.         ' Enumerate all the stack frame objects.
  632.         ' (0-th frame corresponds to the current routine.)
  633.         For i = 0 To st.FrameCount - 1
  634.             ' Get the I-th stack frame and print the method name.
  635.             Dim sf As System.Diagnostics.StackFrame = st.GetFrame(i)
  636.             Console.WriteLine(sf.GetMethod.Name)
  637.         Next
  638.     End Sub
  639.  
  640.     ' this procedure tests the StackFrame from an Exception
  641.  
  642.     Sub TestStackFrameFromException()
  643.         Try
  644.             ' This causes an exception.
  645.             TestStackFrameFromException_1(1)
  646.         Catch e As Exception
  647.             DisplayExceptionInfo(e)
  648.         End Try
  649.     End Sub
  650.  
  651.     Sub TestStackFrameFromException_1(ByVal x As Integer)
  652.         TestStackFrameFromException_2("abc")
  653.     End Sub
  654.  
  655.     Function TestStackFrameFromException_2(ByVal x As String) As String
  656.         TestStackFrameFromException_3()
  657.     End Function
  658.  
  659.     Sub TestStackFrameFromException_3()
  660.         ' Cause an exception (null reference).
  661.         Dim o As Object
  662.         Console.Write(o.ToString)
  663.     End Sub
  664.  
  665.     ' A reusable routine that displays error information
  666.     Sub DisplayExceptionInfo(ByVal e As Exception)
  667.         ' Display the error message.
  668.         Console.WriteLine(e.Message)
  669.  
  670.         Dim st As New StackTrace(e, True)
  671.         Dim i As Integer
  672.  
  673.         For i = 0 To st.FrameCount - 1
  674.             ' Get the i-th stack frame.
  675.             Dim sf As StackFrame = st.GetFrame(i)
  676.             ' Get the corresponding method for that stack frame.
  677.             Dim mi As MemberInfo = sf.GetMethod
  678.             ' Get the namespace where that method is defined.
  679.             Dim res As String = mi.DeclaringType.Namespace & "."
  680.             ' Append the type name.
  681.             res &= mi.DeclaringType.Name & "."
  682.             ' Append the name of the method.
  683.             res &= mi.Name
  684.             ' Append information about the position in source file
  685.             ' (but only if Debug information is available).
  686.             If sf.GetFileName <> "" Then
  687.                 res &= " (" & sf.GetFileName & ", Line " & sf.GetFileLineNumber _
  688.                     & ", Col " & sf.GetFileColumnNumber
  689.             End If
  690.             ' Append information about offset in MSIL code, if available.
  691.             If sf.GetILOffset <> StackFrame.OFFSET_UNKNOWN Then
  692.                 res &= ", IL offset " & sf.GetILOffset.ToString
  693.             End If
  694.             ' Append information about offset in native code.
  695.             res &= ", native offset " & sf.GetNativeOffset & ")"
  696.  
  697.             Console.WriteLine(res)
  698.         Next
  699.     End Sub
  700.  
  701. End Module
  702.  
  703.